# blockchain
from coin.blockchain.hw_wallet.private_client import HwWalletPrivateClient

# only supports korea exchanges
from coin.exchange.base.kr_rest.order_base import TypedOrderBase

# DEX Uniswap
from coin.exchange.uniswap_v3.kr_rest.private_client_v2 import UniswapWalletPrivateClient


class OkexV1Order(TypedOrderBase):
  from coin.exchange.okex.kr_rest.private_client import OkexPrivateClient
  ProductType = OkexPrivateClient.ProductType
  PrivateClientType = OkexPrivateClient


class BinanceOrder(TypedOrderBase):
  from coin.exchange.binance.kr_rest.private_client import BinancePrivateClient
  ProductType = BinancePrivateClient.ProductType
  PrivateClientType = BinancePrivateClient


def generate_private_client(market_type, exchange, api_version, key_file, proxy=None):
  if exchange == "HwWallet":
    assert api_version == 'v1'
    return HwWalletPrivateClient(key_file)
  elif exchange == "Uniswap" and api_version in ('v3', 'v3-arbitrum'):
    return UniswapWalletPrivateClient(
      key_file, mea=f'{market_type}.{exchange}.{api_version}')
  else:
    raise NotImplementedError(exchange)


def generate_order_subscriber(market_type, exchange, api_version, product, key_file):
  from coin.exchange.bithumb.kr_rest.order_client import BithumbOrder
  from coin.exchange.bithumb.kr_rest_web.order_client import BithumbWebOrder
  from coin.exchange.coinone_v2.kr_rest.order_client import CoinoneV2Order
  from coin.exchange.upbit_v1.kr_rest.order_client import UpbitV1Order
  from coin.exchange.bitmex.kr_rest.order_client import BitmexOrder

  # in the order of exchange from coin_proto
  if exchange == "Bitfinex":
    if (api_version == "v2" or api_version is None):
      raise NotImplementedError()
    elif (api_version == "v1"):
      return NotImplementedError()
  if exchange == "Bithumb":
    if api_version == 'web':
      return BithumbWebOrder(product, key_file)
    else:
      assert api_version == 'v2'
      return BithumbOrder(product, key_file)
  elif exchange == "Coinone":
    assert api_version == "v2" or api_version is None
    return CoinoneV2Order(product, key_file)
  elif exchange == "Upbit":
    assert api_version == "v1" or api_version is None
    return UpbitV1Order(product, key_file)
  elif exchange == "Bitmex":
    assert api_version == "v1"
    return BitmexOrder(product, key_file)
  elif exchange == "Okex":
    assert api_version == "v1" or api_version is None
    return OkexV1Order(product, key_file)
  elif exchange == "Binance":
    assert api_version in ('snapshot', 'v1', 'v1-delivery', None)
    return BinanceOrder(product, key_file)
  else:
    raise NotImplementedError(exchange)
